
#include "BN_config.h"
#include "BN_common.h"
#include "BN_data_chain.h"

/**
 * @brief
 *
 * @param hd
 * @return _BN_Data_block_t*
 */
_BN_Data_block_t *BN_block_apply(BN_handler_t *hd)
{
    BN_atom_lock();
    _BN_Data_block_t *ret = hd->malloc(sizeof(_BN_Data_block_t));
    BN_atom_unlock();
    if (ret == BN_NULL)
        return BN_NULL;
    return ret;
}

/**
 * @brief
 *
 * @param hd
 * @param block
 */
void BN_block_free(BN_handler_t *hd, _BN_Data_block_t *block)
{
    BN_atom_lock();
    hd->free(block);
    BN_atom_unlock();
}

/**
 * @brief
 *
 * @param hd
 * @param block
 */
void BN_data_push_list(BN_handler_t *hd, _BN_Data_block_t *block)
{
    BN_atom_lock();

    if (hd->rec.root == 0)
    {
        hd->rec.root = block;
        hd->rec.end = block;
    }
    else
    {
        hd->rec.end->next = block;
        hd->rec.end = block;
    }
    block->next = BN_NULL;
    BN_atom_unlock();
    hd->free(block);
}

/**
 * @brief
 *
 * @param hd
 * @param block
 */
_BN_Data_block_t *BN_data_peek(BN_handler_t *hd, _BN_Data_block_t *current)
{
    BN_atom_lock();
    _BN_Data_block_t *ret;
    if (current == BN_NULL)
        ret = hd->rec.root;
    else
        ret = current->next;
    BN_atom_unlock();
    return ret;
}

/**
 * @brief
 *
 * @param hd
 * @return _BN_Data_block_t*
 */
_BN_Data_block_t *BN_data_pop(BN_handler_t *hd)
{
    BN_atom_lock();
    _BN_Data_block_t *ret;
    if (hd->rec.root == BN_NULL)
        ret = BN_NULL;
    else
    {
        ret = hd->rec.root;
        hd->rec.root = hd->rec.root->next;
    }
    BN_atom_unlock();
    return ret;
}

/**
 * @brief
 *
 * @param hd
 * @param index
 * @return _BN_Data_block_t*
 */
_BN_Data_block_t *BN_data_search(BN_handler_t *hd, int index)
{
    _BN_Data_block_t *ret;
    int i;
    for (i = 0, ret = hd->rec.root; i < index && ret != BN_NULL; i++, ret = ret->next)
        ;
    return ret;
}
